/*
 * Copyright 2013-2019 Xia Jun(3979434@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************************************
 *                                                                                     *
 *                        Website : http://www.farsunset.com                           *
 *                                                                                     *
 ***************************************************************************************
 */
package com.workcell.workdata.im.service.impl;

import com.workcell.workdata.im.component.event.PushMessageEvent;
import com.workcell.workdata.im.component.redis.FriendRedisTemplate;
import com.workcell.workdata.im.constant.MessageAction;
import com.workcell.workdata.im.entity.EventMessage;
import com.workcell.workdata.im.entity.Friend;
import com.workcell.workdata.im.entity.Message;
import com.workcell.workdata.im.model.request.FriendAlisaRequest;
import com.workcell.workdata.im.model.vo.UserVO;
import com.workcell.workdata.im.repository.FriendRepository;
import com.workcell.workdata.im.repository.UserRepository;
import com.workcell.workdata.im.service.FriendService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class FriendServiceImpl implements FriendService {

	@Resource
	private FriendRepository friendRepository;

	@Resource
	private UserRepository userRepository;

	@Resource
	private ApplicationContext applicationContext;

	@Resource
	private FriendRedisTemplate friendRedisTemplate;

	@Override
	@Transactional
	public void add(Friend friend) {

		if (!friendRepository.isFriend(friend.getUid(),friend.getFid())){
			friend.setCreateTime(new Date());
			friendRepository.saveAndFlush(friend);
			friendRedisTemplate.add(friend.getUid(),friend.getFid());
		}

		if (friendRepository.isFriend(friend.getFid(),friend.getUid())){
			return;
		}

		Friend newFriend = new Friend();
		newFriend.setUid(friend.getFid());
		newFriend.setFid(friend.getUid());
		newFriend.setCreateTime(new Date());
		friendRepository.saveAndFlush(newFriend);
		friendRedisTemplate.add(newFriend.getUid(),newFriend.getFid());

		Message message = new EventMessage();
		message.setSender(friend.getUid());
		message.setReceiver(friend.getFid());
		message.setAction(MessageAction.ACTION_106);
		applicationContext.publishEvent(new PushMessageEvent(message));
	}

	@Override
	public void setAlias(Long uid, FriendAlisaRequest request) {
		friendRepository.updateAlias(uid,request.getUid(),request.getAlias());
	}


	@Override
	public List<UserVO> findList(Long uid) {
		Map<Long,String> aliasMap = findAliasMap(uid);
		return userRepository.findList(aliasMap.keySet()).stream().map(user -> UserVO.of(user,aliasMap.get(user.getId()))).collect(Collectors.toList());
	}

	@Override
	@Transactional
	public void delete(Long uid,Long fid) {

		friendRepository.remove(fid,uid);

		friendRepository.remove(uid,fid);

		friendRedisTemplate.delete(fid,uid);
		friendRedisTemplate.delete(uid,fid);

		Message message = new EventMessage();
		message.setSender(uid);
		message.setReceiver(fid);
		message.setAction(MessageAction.ACTION_107);

		applicationContext.publishEvent(new PushMessageEvent(message));
	}


	@Override
	public boolean isFriend(Long uid, Long fid) {
		if (friendRedisTemplate.isFriend(uid,fid)){
			return true;
		}
		return friendRepository.isFriend(uid,fid);
	}


	@Override
	public List<Long> findUidList(Long uid) {
		List<Long> fidList = friendRedisTemplate.findUidList(uid);
		if (fidList.isEmpty()){
			fidList.addAll(friendRepository.findUidList(uid));
			friendRedisTemplate.add(uid,fidList);
		}
		return fidList;
	}

	@Override
	public Map<Long, String> findAliasMap(Long uid) {
		Map<Long,String> aliasMap = new HashMap<>();
		List<Friend> friends = friendRepository.findList(uid);
		for (Friend friend : friends){
			aliasMap.put(friend.getFid(),friend.getAlias());
		}
		return aliasMap;
	}

	@Override
	public boolean isCallable(long fromId, long toId) {
		return isFriend(toId,fromId);
	}

}
